const { series, src, parallel, dest, watch } = require('gulp');
const del = require('del');
const gulpLoadPlugins = require('gulp-load-plugins');
const browserSync = require('browser-sync');
const config = require('./config.json');

const bs = browserSync.create();
const plugins = gulpLoadPlugins();

// Clean
const clean = () => del([config.output]);

const sassLint = () =>
	src(config.styles).pipe(plugins.sassLint()).pipe(plugins.sassLint.format());

const esLint = () =>
	src(config.scripts)
		.pipe(plugins.eslint.format())
		.pipe(plugins.eslint.failAfterError());

// 编译scss
const style = () =>
	src(config.styles, {base: config.entry})
		.pipe(plugins.sass({outputStyle: 'expanded'}))
		.pipe(dest(config.output))
		.pipe(bs.reload({stream: true}));

// 编译js
const script = () =>
	src(config.scripts, {base: config.entry})
		.pipe(plugins.babel({presets: ['@babel/preset-env']}))
		.pipe(dest(config.output))
		.pipe(bs.reload({stream: true}));

const data = {
	menus: [
		{
			name: 'Home',
			link: 'index.html',
		},
		{
			name: 'About',
			link: 'about.html',
		},
	],
	pkg: require('./package.json'),
	date: new Date(),
};

// 编译html
const page = () =>
	src(config.pages, {base: config.entry})
		.pipe(plugins.swig({data}))
		.pipe(dest(config.output))
		.pipe(bs.reload({stream: true}));

const images = () =>
	src(config.images, {base: config.entry})
		.pipe(plugins.imagemin())
		.pipe(dest(config.output));

const fonts = () =>
	src(config.fonts, {base: config.entry})
		.pipe(plugins.imagemin())
		.pipe(dest(config.output));

const public = () =>
	src(config.static, {base: config.public}).pipe(dest(config.output));

const useref = () =>
	src('dist/*.html', {base: config.output})
		.pipe(plugins.useref({searchPath: ['dist', '.']}))
		.pipe(plugins.if(/\.js$/, plugins.uglify()))
		.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
		.pipe(
			plugins.if(
				/\.html$/,
				plugins.htmlmin({
					collapseWhitespace: true,
					minifyCSS: true,
					minifyJS: true,
				}),
			),
		)
		.pipe(dest(config.output));

const serve = () => {
	watch(config.styles, style);
	watch(config.scripts, script);
	watch(config.pages, page);
	watch([config.images, config.fonts, config.static], bs.reload);

	return bs.init({
		notify: false,
		port: 2080,
		server: {
			baseDir: [config.output, config.entry, config.public],
			routes: {
				'/node_modules': 'node_modules',
			},
		},
	});
};

const deploy = () => plugins.gitDeploy({remote: 'origin', name: 'master'});

const compile = parallel(style, script, page);

const build = series(
	clean,
	parallel(series(compile, useref), images, fonts, public),
);

const start = series(compile, serve);

const lint = series(sassLint, esLint);

module.exports = {clean, lint, compile, serve, build, start, deploy};
